package com.app.baselibrary.http

import com.app.baselibrary.http.flow.FlowCallAdapterFactory
import com.app.baselibrary.ktx.gson
import com.app.baselibrary.utils.LogUtil
import okhttp3.Call
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.X509TrustManager

/**
 * http config
 */
object HttpConfig {

    //API访问地址
    private var mBaseUrl: String? = null


    private val manager = object : X509TrustManager {

        override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) {}

        override fun checkServerTrusted(p0: Array<out X509Certificate>?, p1: String?) {}

        override fun getAcceptedIssuers(): Array<X509Certificate> {
            return arrayOf()
        }

    }

    /**
     * 修改访问地址
     * @param type
     */
    private fun getBaseUrl(type: Int) {
        when (type) {
            0 ->{
                //必应每日一图
                mBaseUrl = "https://cn.bing.com"
            }

            1 ->{
                //网络手机壁纸返回地址
                mBaseUrl = "http://service.picasso.adesk.com"
            }

            2 ->{
                //每日一言
                mBaseUrl = "https://v.api.aa1.cn"
            }
            3 ->{
                //小视频
                mBaseUrl = "https://tucdn.wpon.cn"
            }
            else -> {}
        }
    }

    val okHttpClient by lazy {
        OkHttpClient.Builder().sslSocketFactory(
            SSLUtil.createSSLContext().socketFactory, manager
        )
            .addInterceptor(AuthHeaderInterceptor())
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .readTimeout(60L, TimeUnit.SECONDS)
            .writeTimeout(60L, TimeUnit.SECONDS)
            .followRedirects(true)
            .connectTimeout(60L, TimeUnit.SECONDS)
            .callTimeout(60L, TimeUnit.SECONDS)
            .followSslRedirects(true)
            .retryOnConnectionFailure(true)
            .hostnameVerifier(HostnameVerifier { _, _ -> true })
            .build()
    }


    /**
     * 只初始化一次
      */
  private val retrofit: Retrofit by lazy{
        Retrofit.Builder()
            .baseUrl(mBaseUrl)
            .addCallAdapterFactory(
                FlowCallAdapterFactory.create<HttpResultException>(
                    HttpExceptionConvert()
                )
            )
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(okHttpClient)
            .build()
    }


    private fun getMultipleRetrofit(): Retrofit{
        //Retrofit构建器
        val builder = Retrofit.Builder()
        //设置访问地址
        builder.baseUrl(mBaseUrl)
        //设置OkHttp客户端，传入上面写好的方法即可获得配置后的OkHttp客户端。
        builder.client(okHttpClient)
        //设置数据解析器 会自动把请求返回的结果（json字符串）通过Gson转化工厂自动转化成与其结构相符的实体Bean
        builder.addConverterFactory(GsonConverterFactory.create(gson))
        //设置请求回调，使用RxJava 对网络返回进行处理
        builder.addCallAdapterFactory( FlowCallAdapterFactory.create<HttpResultException>(
            HttpExceptionConvert()
        ))
        //retrofit配置完成
        val retrofit = builder.build()
        //最后返回即可
        return retrofit
    }

    /**
     * 创建serviceClass的实例
     */
      fun <T> createService(serviceClass: Class<T>, type: Int): T {
        getBaseUrl(type)
        return retrofit.create<T>(serviceClass)
     }

    fun <T> createMultipleService(serviceClass: Class<T>, type: Int): T {
        getBaseUrl(type)
        return getMultipleRetrofit().create<T>(serviceClass)
    }

    /**
     * 构建[Call]
     */
    fun newCall(request: Request): Call {
        return okHttpClient.newCall(request)
    }

    /**
     * 关闭请求
     */
    fun closeCall(tag: Any) {
        okHttpClient.dispatcher.queuedCalls().forEach {
            if (it.request().tag() == tag) {
                it.cancel()
            }
        }
        okHttpClient.dispatcher.runningCalls().forEach {
            if (it.request().tag() == tag) {
                it.cancel()
            }
        }
    }


}